package result

import (
	"fmt"
	"net/http"

	"go-zero-admin/pkg/xerr"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpx"
	"google.golang.org/grpc/status"
)

// HttpResult http response
func HttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {
	if err == nil {
		// return success
		r := Success(resp)
		httpx.WriteJson(w, http.StatusOK, r)
	} else {
		// return error
		errCode := xerr.ServerCommonError
		// default error msg
		errMsg := xerr.MapErrMsg(errCode)

		// err type
		causeErr := errors.Cause(err)
		// custom error type
		if e, ok := causeErr.(*xerr.CodeError); ok {
			// custom code error
			errCode = e.GetErrCode()
			errMsg = e.GetErrMsg()
		} else {
			// grpc error
			if gStatus, ok := status.FromError(causeErr); ok {
				// grpc error by uint32 convert
				grpcCode := uint32(gStatus.Code())
				// 区分自定义错误跟系统底层、db等错误，底层、db错误不能返回给前端
				if xerr.IsCodeErr(grpcCode) {
					errCode = grpcCode
					errMsg = gStatus.Message()
				}
			}
		}

		logx.WithContext(r.Context()).Errorf("【API-ERR】%s: %+v", r.RequestURI, err)

		httpx.WriteJson(w, http.StatusOK, Error(errCode, errMsg))
	}
}

// AuthHttpResult http auth error
func AuthHttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {
	if err == nil {
		// return success
		r := Success(resp)
		httpx.WriteJson(w, http.StatusOK, r)
	} else {
		// return error
		errCode := xerr.ServerCommonError
		errMsg := xerr.MapErrMsg(errCode)

		// error type
		causeErr := errors.Cause(err)
		// custom error type
		if e, ok := causeErr.(*xerr.CodeError); ok {
			//  custom code error
			errCode = e.GetErrCode()
			errMsg = e.GetErrMsg()
		} else {
			// grpc error
			if gStatus, ok := status.FromError(causeErr); ok {
				grpcCode := uint32(gStatus.Code())
				// 区分自定义错误跟系统底层、db等错误，底层、db错误不能返回给前端
				if xerr.IsCodeErr(grpcCode) {
					errCode = grpcCode
					errMsg = gStatus.Message()
				}
			}
		}

		logx.WithContext(r.Context()).Errorf("【API-ERR】%s: %+v", r.RequestURI, err)

		httpx.WriteJson(w, http.StatusOK, Error(errCode, errMsg))
	}
}

// ParamErrorResult http param error
func ParamErrorResult(r *http.Request, w http.ResponseWriter, err error) {
	errMsg := fmt.Sprintf("%s ,%s", xerr.MapErrMsg(xerr.RequestParamError), err.Error())
	httpx.WriteJson(w, http.StatusOK, Error(xerr.RequestParamError, errMsg))
}
